// create scrabble namespace
var scrabble = {};

/**
 * Remove an element from an array object.
 * @param {Object} value An element to be removed.
 */ 
Array.prototype.remove = function(value) {	
  for (var i = 0; i < this.length; i++) {
    if (this[i] == value) {
	  this.splice(i, 1);
      break;
    }
  }
};

/**
 * Check if an object exists in an array.
 * @param {object} object The number to be looked for in the array.
 * @return {Boolean} True/false to whether the number exists in the array.
 */   
Array.prototype.contains = function(object) {
  var ret = false;
  for (var i = 0; i < this.length; i++) {
    if (this[i] == object) {
      ret = true;
      break;
    }
  }  
  return ret;
};

/**
 * Remove an Array of elements from an array object.
 * @param {Array} All the elements in the given array will be removed for the array object.
 */  
Array.prototype.removeArray = function(array) {  
 // var returnAray;    
  if (!array instanceof Array) {
    return this;
  }
  else {
       for (var i = 0; i < array.length; i++) {
        for (var j = 0; j < this.length; j++){
          if(this[j] == array[i])
		  {
		    this.splice(j, 1);
			break;
		  } 	
		}
      }
	}    
 return this;
};


Array.prototype.addArray = function(array) {  
 // var returnAray;    
  if (!array instanceof Array) {
	    return this;
  }
  else {
        for (var j = 0; j < array.length; j++){
          this.push(array[j]);
      }
    } 
 return this;
};


Array.prototype.shuffle = function() {       
  for (var i = 0; i < this.length; i++) {
  
    var newPos = parseInt(Math.random() * i);
    
    var current = this[i];
    var temp = this[newPos];
    
    this[newPos] = current;
    this[i] = temp;
  }          
};

scrabble.drag = (function () {

	//
	// private parameters
	//
	
	var	obj_margin = null,		// space from clicked point to the object bounds (top, right, bottom, left)
		mouseButton = 0,		// if mouseButton == 1 then first mouse button is pressed
		mouseX = null,			// mouse coordinates (used in onmousedown, onmousemove and autoscroll)
		mouseY = null,
		window_width = 0,		// window width and height (parameters are set in onload and onresize event handler)
		window_height = 0,
		scroll_width = null,	// scroll width and height of the window (it is usually greater then window)
		scroll_height = null,
		edgeX = 0,				// autoscroll bound values (closer to the page edge, faster scroll) calculated in onmousemove handler
		edgeY = 0,
		bgcolor_old = null,		// old cell background color
		tables = null,			// table offsets and row offsets (initialized in onload event)
		autoscrollX_flag = 0,	// needed to prevent multiple calls of autoscrollX and autoscrollY from onmousemove event handler
		autoscrollY_flag = 0,
		moved_flag = 0,			// if object is moved, flag gets value 1  
				
		// selected, previous and source table, row and cell
		table = null,
		table_old = null,
		table_source = null,
		row = null,
		row_old = null,
		row_source = null,
		cell = null,
		cell_old = null,
		cell_source = null,
		currentTokens = [];
		triplewordTokens = [0,7,14,105,119,210,217,224];
		doublewordTokens = [16,28,32,42,48,56,64,70,112,154,160,168,176,182,192,196,208];
		doubleletterTokens = [3,11,36,38,45,52,59,92,96,98,102,108,116,122,126,128,132,165,172,179,186,188,213,221];
		tripleletterTokens = [20,24,76,80,84,88,136,140,144,148,200,204];
		tokenValues = {};
		//
	// private methods
	//
	
	// onresize window event handler
	// this event handler sets window_width and window_height variables used in onmousemove handler
	function handler_onresize () {
		// Non-IE
		if (typeof(window.innerWidth) === 'number') {
			window_width  = window.innerWidth;
			window_height = window.innerHeight;
		}
		// IE 6+ in 'standards compliant mode'
		else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
			window_width  = document.documentElement.clientWidth;
			window_height = document.documentElement.clientHeight;
		}
		// IE 4 compatible
		else if (document.body && (document.body.clientWidth || document.body.clientHeight)) {
			window_width  = document.body.clientWidth;
			window_height = document.body.clientHeight;
		}
		// set scroll size (onresize, onload and onmouseup event)
		scroll_width  = document.documentElement.scrollWidth;
		scroll_height = document.documentElement.scrollHeight;
		// calculate colums and rows offset (cells dimensions)
		calculate_cells();  
	};


	
	// onmousedown handler
	function handler_onmousedown (e){
		// define event (cross browser)
		var evt = e || window.event;
		// enable control for form elements
		if (elementControl(evt)) return true;
		// set reference to the clicked object
		obj = this;
		obj.style.zIndex = 999;
		// set clicked position
		mouseX = evt.clientX;
		mouseY = evt.clientY;
		// set current table, row and cell
		set_tcr(evt);
		// remember start position (table, row and cell)
		table_source = table;
		row_source   = row;
		cell_source  = cell;
		// define pressed mouse button
		if (evt.which) mouseButton = evt.which;
		else           mouseButton = evt.button;
		// activate onmousemove and onmouseup event handlers on document level
		// if left mouse button is pressed
		if (mouseButton == 1){
			moved_flag  = 0; // reset moved_flag 
			document.onmousemove = handler_onmousemove;
			document.onmouseup   = handler_onmouseup;
		//	scrabble.drag.myhandler_clicked(); // call myhandler (public method)
		}
		// remember background cell color
		bgcolor_old = tables[table].rows[row].cells[cell].style.backgroundColor;
		// define object offset
		var offset = box_offset(obj);
		// calculate ofsset from the clicked point inside element to the
		// top, right, bottom and left side of the element
		obj_margin = [mouseY-offset[0], offset[1]-mouseX, offset[2]-mouseY, mouseX-offset[3]];
		// disable text selection
		return false;
	};
	


	// onmouseup handler
	function handler_onmouseup (e){
	
		var currentUser = get('currentUser');
		
		// define destination and source table cell
		var destination_cell, source_cell;
		// define destination elements and destination elements length needed for switching table cells
		// destination_elements_length is needed because nodeList objects in the DOM are live 		
		var destination_elements, destination_elements_length;
		// reset mouseButton variable
		mouseButton = 0;
		// reset left and top styles
		obj.style.left = 0;
		obj.style.top  = 0;
		// return z-index
		obj.style.zIndex = 10;
		// if object was dropped inside table then define a new location for destination cell
		if (table < tables.length){
			destination_cell = tables[table].rows[row].cells[cell];
		}
		// if any level of old position is undefined, then use source location
		else if (table_old == null || row_old == null || cell_old == null) {
			destination_cell = tables[table_source].rows[row_source].cells[cell_source];
		}
		// or use the previous location
		else{
			destination_cell = tables[table_old].rows[row_old].cells[cell_old];
		}
		
		if(currentUser != wave.getViewer().getId())
		{
			destination_cell = tables[table_source].rows[row_source].cells[cell_source];
		}	
		// return background color for destination color (cell had hover color)
		//destination_cell.style.backgroundColor = bgcolor_old;
		// detach onmousemove and onmouseup events
		document.onmousemove = null;
		document.onmouseup   = null;
		// document.body.scroll... only works in compatibility (aka quirks) mode,
		// for standard mode, use: document.documentElement.scroll...
		scroll_width  = document.documentElement.scrollWidth;
		scroll_height = document.documentElement.scrollHeight;	
		// reset autoscroll flags
		autoscrollX_flag = autoscrollY_flag = 0;
		// reset old positions
		table_old = row_old = cell_old = null;
		// element was moved
		if (moved_flag != 0){
			scrabble.drag.myhandler_dropped();
			//can we move the following code inside the above handler?
			
			var cell_className = tables[table_source].rows[row_source].cells[cell_source];
			var cellId = jQuery('#'+ cell_className.id);
			if(cell_className.className.indexOf(scrabble.drag.tripleWord) > -1)
				cellId.html(scrabble.drag.tripleWordText);
			else if(cell_className.className.indexOf(scrabble.drag.doubleWord) > -1)
				cellId.html(scrabble.drag.doubleWordText);
			else if(cell_className.className.indexOf(scrabble.drag.tripleLetter) > -1)
				cellId.html(scrabble.drag.tripleLetterText);
			else if(cell_className.className.indexOf(scrabble.drag.doubleLetter) > -1)
				cellId.html(scrabble.drag.doubleLetterText);
			jQuery('#'+ destination_cell.id).html("");
			destination_cell.appendChild(obj);
			/*source_cell = tables[table_source].rows[row_source].cells[cell_source];
			if(containsCell(currentTokens, source_cell))
			  removeCell(currentTokens,source_cell);
			currentTokens.push(destination_cell);*/
			
		}
		// force naughty browsers (IE6, IE7 ...) to redraw source and destination row (element.className = element.className does the trick)
		tables[table_source].rows[row_source].className = tables[table_source].rows[row_source].className;
		destination_cell.parentNode.className = destination_cell.parentNode.className;
		// recalculate table cells and scrollers because cell content could change row dimensions 
	//	calculate_cells();
	};
	
	
	// onmousemove handler for the document level
	// activated after left mouse button is pressed on draggable element
	function handler_onmousemove (e){
		// define event (FF & IE)
		var evt = e || window.event;
		var bound = scrabble.drag.bound;
		// object is only moved, call myhandler_moved
		if (moved_flag == 0){
			scrabble.drag.myhandler_moved();
		}
		// set moved_flag
		moved_flag = 1;
		// set left and top styles for the moved element if element is inside window
		// this conditions will stop element on window bounds
		if (evt.clientX > obj_margin[3] && evt.clientX < window_width - obj_margin[1])  obj.style.left = (evt.clientX - mouseX) + "px";
		if (evt.clientY > obj_margin[0] && evt.clientY < window_height - obj_margin[2]) obj.style.top  = (evt.clientY - mouseY) + "px";
		// set current table, row and cell
		set_tcr(evt);
		// if new location is inside table and new location is different than old location
		// set background colors for the previous and new table cell
		if (table < tables.length && (table != table_old || cell != cell_old || row != row_old)){
			// set cell background color to the previous cell
			if (table_old != null && row_old != null && cell_old != null)
				tables[table_old].rows[row_old].cells[cell_old].style.backgroundColor = bgcolor_old;
			// remember background color before setting the new background color
			bgcolor_old = tables[table].rows[row].cells[cell].style.backgroundColor;
			// remember current position (for table, row and cell)
			table_old=table; row_old=row; cell_old=cell;
		}
		// test if is still first mouse button pressed (in case when user release mouse button out of a window)
		if (evt.which) mouseButton = evt.which;
		else           mouseButton = evt.button;
		// if first mouse button is released
		if (mouseButton != 1){handler_onmouseup(evt); return;}	
		// calculate horizontally crossed page bound
		edgeX = bound - (window_width/2  > evt.clientX ? evt.clientX-obj_margin[3] : window_width - evt.clientX - obj_margin[1]);
		// if element crosses page bound then set scroll direction and call auto scroll 
		if (edgeX > 0){
			// in case when object is only half visible (page is scrolled on that object)
			if (edgeX > bound) edgeX = bound;
			// set scroll direction: negative - left, positive - right
			edgeX *= evt.clientX < window_width/2 ? -1 : 1; 
			// remove onscroll event handler and call autoscrollY function only once
			if (autoscrollX_flag++ == 0) {window.onscroll = null; autoscrollX()}
		}
		else edgeX = 0;
		// calculate vertically crossed page bound
		edgeY = bound - (window_height/2 > evt.clientY ? evt.clientY-obj_margin[0] : window_height - evt.clientY - obj_margin[2]);
		// if element crosses page bound then set scroll direction and call auto scroll
		if (edgeY > 0){
			// in case when object is only half visible (page is scrolled on that object)
			if (edgeY > bound) edgeY = bound;
			// set scroll direction: negative - up, positive - down
			edgeY *= evt.clientY < window_height/2 ? -1 : 1;
			// remove onscroll event handler and call autoscrollY function only once
			if (autoscrollY_flag++ == 0) {window.onscroll = null; autoscrollY()}
		}
		else edgeY = 0;
		// stop all propagation of the event in the bubbling phase.
		// (save system resources by turning off bubbling)
		evt.cancelBubble = true;
		if (evt.stopPropagation) evt.stopPropagation();
	};
	
	//
	// auto scroll functions
	//
		
	// horizontal auto scroll function
	function autoscrollX (call){
		// define old scroll position and current scroll position
		var old = 0; 
		var scrollPosition = getScrollPosition('X');
		// mouse button should be pressed and
		// if moved element is over left or right margin
		// scroll_width - window_width returns maximum horizontal scroll position
		if (mouseButton == 1 && ((edgeX < 0 && scrollPosition > 0) || (edgeX > 0 && scrollPosition < (scroll_width - window_width)))){
			// horizontal window scroll 
			window.scrollBy(edgeX, 0);
			// set previous scroll position and new after window is scrolled
			old = scrollPosition;
			scrollPosition = getScrollPosition('X');
			// set style left for the moved element
			obj.style.left = (parseInt(obj.style.left) + scrollPosition - old) + "px";
			// move X point
			mouseX -= scrollPosition - old; 
			// recursive autoscroll call 
			setTimeout("scrabble.drag.autoscrollX('recursive')", scrabble.drag.speed);
		}
		// autoscroll stopped by moving element out of the page edge
		// or element faced maximum position (left or right)
		else{
			// recalculate cell positions if call was function itself (spare CPU if moving object across bound)
			if (call == 'recursive') calculate_cells();
			// return onscroll event handler and reset auto scroll flag
			window.onscroll  = calculate_cells;
			autoscrollX_flag = 0;
		}
	};
	

	
	// vertical auto scroll function
	function autoscrollY (call){
		var top;     // top style
		var old = 0; // define old scroll position
		// define current scroll position
		var scrollPosition = getScrollPosition('Y');
		// mouse button should be pressed and 
		// if moved element is over page top or page bottom
		// scroll_height - window_height returns maximum vertical scroll position
		if (mouseButton == 1 && ((edgeY < 0 && scrollPosition > 0) || (edgeY > 0 && scrollPosition < (scroll_height - window_height)))){
			// vertical window scroll 
			window.scrollBy(0, edgeY);
			// set previous scroll position and new after window is scrolled
			old = scrollPosition;
			scrollPosition = getScrollPosition('Y');
			// set top style of the object
			top = (isNaN(parseInt(obj.style.top)) ? 0 : parseInt(obj.style.top));
			// set style top for the moved element
			obj.style.top = (top + scrollPosition - old) + "px";
			// move Y point
			mouseY -= scrollPosition - old; 
			// recursive autoscroll call 
			setTimeout("scrabble.drag.autoscrollY('recursive')", scrabble.drag.speed);
		}
		// autoscroll stopped by moving element out of the page edge
		// or element faced maximum position (top or bottom)
		else{
			// recalculate cell positions if call was function itself (spare CPU if moving object across bound)
			if (call == 'recursive') calculate_cells();
			// return onscroll event handler and reset auto scroll flag
			window.onscroll  = calculate_cells;
			autoscrollY_flag = 0;
		}
	};
	
	
	
	// function returns scroll position for X or Y scrollbar
	// input parameter is dimension (X or Y)
	function getScrollPosition (d){
		var scrollX, scrollY; // define local scroll position variables
		// Netscape compliant
	  if (typeof(window.pageYOffset) == 'number'){
	    scrollX = window.pageXOffset;
	    scrollY = window.pageYOffset;
	  }
	  // DOM compliant
	  else if (document.body && (document.body.scrollLeft || document.body.scrollTop)){
	    scrollX = document.body.scrollLeft;
	    scrollY = document.body.scrollTop;
	  }
	  // IE6 standards compliant mode
	  else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)){
	    scrollX = document.documentElement.scrollLeft;
	    scrollY = document.documentElement.scrollTop;
	  }
	  // needed for IE6 (when vertical scroll bar was on the top)
	  else scrollX = scrollY = 0;
	  // return scroll position
	  if (d == 'X') return scrollX;
	  else          return scrollY
	};
	
	
	
	//
	// other functions
	//
	
	
	
	// calculate table colums and row offsets (cells dimensions) 
	function calculate_cells (){
		var i, j,		// local variables used in loops
			tr,			// row collection in current table
			row_offset;	// row box
		// open loop for each HTML table inside id=drag (tables variable is initialized in onload event)
		for (i=0; i<tables.length; i++){
			// initialize row_offset array
			row_offset = new Array();
			// collect table rows and initialize row offsets array
			tr = tables[i].getElementsByTagName('tr');
			// backward loop has better perfomance
			for (j=tr.length-1; j>=0; j--) {
				row_offset[j] = box_offset(tr[j]);
			}
			// save table informations (table offset and row offsets)
			tables[i].offset     = box_offset(tables[i]);
			tables[i].row_offset = row_offset;
		}
	};
	
	
	
	// function sets current table, row and cell
	// please note that variables used in this function (table, cell and row)
	// are defined at the beginning of the script (global scope) 
	function set_tcr (evt){
		// define variables for left & right cell offset
		var offsetLeft, offsetRight;
		// define current cell (needed for some test at the function bottom)
		var cell_current;
		// find table below draggable object
		for (table=0; table < tables.length; table++){
			// mouse pointer is inside table
			if (tables[table].offset[3] < evt.clientX  &&  evt.clientX < tables[table].offset[1] &&	
				tables[table].offset[0] < evt.clientY  &&  evt.clientY < tables[table].offset[2]){
						// row offsets for the selected table (row box bounds)
						var row_offset = tables[table].row_offset;
						// find the current row (loop will stop at the current row; row_offset[row][0] is row top offset)
						for (row=0; row<row_offset.length-1 && row_offset[row][0] < evt.clientY; row++){
							// top bound of the next row
							if (evt.clientY <= row_offset[row+1][0]) break;
						}
						// do loop - needed for rowspaned cells (if there is any)
						do{
							// set the number of cells in the selected row
							var cells = tables[table].rows[row].cells.length - 1;
							// find current cell (X mouse position between cell offset left and right)
							for (cell = cells; cell >= 0; cell--){
								// row left offset + cell left offset
								offsetLeft = row_offset[row][3] + tables[table].rows[row].cells[cell].offsetLeft;
								// cell right offset is left offset + cell width  
								offsetRight = offsetLeft + tables[table].rows[row].cells[cell].offsetWidth;
								// is mouse pointer is between left and right offset, then cell is found
								if (offsetLeft <= evt.clientX && evt.clientX < offsetRight) break;
							}
						} // mouse pointer is inside table but cell not found (hmm, rowspaned cell - try in upper row)
						while (cell == -1 && row-- > 0)
						// if cell < 0 or row < 0 use last possible location
						if (row < 0 || cell < 0) {table=table_old; row=row_old; cell=cell_old;}
						// set current cell
						cell_current = tables[table].rows[row].cells[cell];
						// if current cell is marked as 'forbid', then return previous location
						if (cell_current.className.indexOf(scrabble.drag.forbid) > -1) {table=table_old; row=row_old; cell=cell_old; break;}
						// if drop_option == single and current cell has child nodes then test if cell is occupied
						if (scrabble.drag.drop_option == 'single' &&	cell_current.childNodes.length > 0){
							// if cell has only one node and that is text node then break - because this is empty cell
							if (cell_current.childNodes.length == 1 && cell_current.firstChild.nodeType == 3) break;
							// define and set has_content flag to false
							var has_content = false;
							// open loop for each child node and jump out if 'drag' className found
							for (var i=cell_current.childNodes.length-1; i>=0 ; i--){
								if (cell_current.childNodes[i].className && cell_current.childNodes[i].className.indexOf('drag') > -1) {has_content = true; break;} 
							}
							// if cell has content and old position exists ...
							if (has_content && table_old != null && row_old != null && cell_old != null){
								// .. and current position is different then source position then return previous position
								if (table_source != table || row_source != row || cell_source != cell) {table=table_old; row=row_old; cell=cell_old; break;}
							}
						}
						// break table loop 
						break;
			}
		}
	};
	
	
	
	// calculate object (box) offset (top, right, bottom, left)
	// function returns array of box bounds
	// used in calculate_cells and onmousedown event handler
	function box_offset (box){
		var oLeft = 0 - getScrollPosition('X'); // define offset left (take care of scroll position)
		var oTop  = 0 - getScrollPosition('Y'); // define offset top (take care od scroll position)
		// remember box object
		var box_old = box;
		// loop to the root element and return box offset (top, right, bottom, left)
		do {oLeft += box.offsetLeft; oTop += box.offsetTop} while (box = box.offsetParent);
		// return box offset array
		//       top               right,                     bottom             left
		return [ oTop, oLeft + box_old.offsetWidth, oTop + box_old.offsetHeight, oLeft ];
	};
	
	// function returns true or false if element needs to have control
	function elementControl (evt) {
		// declare form element and source tag name
		var formElement;
		var srcName;
		// set source tag name for IE and FF
		if (evt.srcElement)	srcName = evt.srcElement.tagName;
		else                srcName = evt.target.tagName;
		// set flag (true or false) for named elements
		switch(srcName){
			case 'A':
			case 'INPUT':
			case 'SELECT':
			case 'OPTION':
				formElement = true;
				break;
			default:
				formElement = false;
		}
		// return formElement flag
	 	return formElement;
	};
	



	// initialization
	function init() {
		//makeTable();
		// define local variables
		var self = this,		// assign reference to current object to "self"
			i,					// for loops
			imgs,				// collect images inside div=drag
			evt,				// event
			tables_nodeList,	// live nodelist of tables found inside div=drag
			maintables_nodeList;
		// collect tables inside div with id=drag and make static nodeList
		tables = Array();
		tables_nodeList = document.getElementById('drag').getElementsByTagName('table');
	  	for (i = 0; i < tables_nodeList.length; i = i + 1) {
			tables[i] = tables_nodeList[i];
		}
		//tables[0] = jQuery('#mainTable');
		//tables[1] = jQuery('#tokenTable');
		
		// set initial window width/height, scroll width/height and define onresize event handler
		// onresize event handler calls calculate columns
		handler_onresize();
		window.onresize = handler_onresize;
		// attach onmousedown event handler to the DIV elements
		enable_drag(true);
		// collect images inside div=drag to prevent default action of onmousemove event (needed for IE to enable dragging on image)
		imgs = document.getElementById('drag').getElementsByTagName('img');
		// disable onmousemove event for images
		for (i = 0; i < imgs.length; i = i + 1) {
			imgs[i].onmousemove = function () {
				return false;
			};
		}
		// dissable text selection for IE (but not for links and form elements)
		document.onselectstart = function (e) {
			evt = e || window.event;
			if (!elementControl(evt)) {
			    return false;
			}
		};
		// attach onscroll event (needed for recalculating table cells positions)
		window.onscroll = calculate_cells;
		
	};



	// function attach / detach onmousedown event for DIV elements
	// input parameter is true or false
	function enable_drag (state) {
		// define local variables
		var i,				// for loop
			divs,			// collection of div elements contained in tables
			borderStyle,	// border style (solid or dotted)
			cursor,			// cursor style (move or auto)
			handler;		// onmousedown handler or null
		// define onmousedown handler and styles or null
		if (state === true) {
			handler = handler_onmousedown;
			borderStyle = 'solid';
			cursor = 'move';
		}
		else {
			handler = null;
			borderStyle = 'dotted';
			cursor = 'auto';
		}
		// collect div elements inside tables (draggable elements)
		divs = document.getElementById('drag').getElementsByTagName('div');
		// attach onmousedown event handler only to DIV elements that have "drag" in class name
		// allow other div elements inside <div id="drag" ...
		for (i = 0; i < divs.length; i = i + 1) { 
			if (divs[i].className.indexOf('drag') > -1) {
				divs[i].onmousedown = handler;
				divs[i].style.borderStyle = borderStyle;
				divs[i].style.cursor = cursor;
			}
		}
	};



	// scan tables, prepare query string and sent to the multiple-parameters.php
	// (fired on button "Save" click :)
	function save_content () {
	/*	// define query parameter
		var query = '';
		// loop through each table
		for (var t=0; t<tables.length; t++){
			// define number of table rows
			var tbl_rows = tables[t].rows.length;
			// iterate through each table row
			for (var r=0; r<tbl_rows; r++){
				// set the number of cells in the current row
				var cells = tables[t].rows[r].cells.length
				// iterate through each table cell
				for (var c=0; c<cells; c++){
					// set reference to the table cell
					var tbl_cell = tables[t].rows[r].cells[c];
					// if cells isn't empty and hasn't forbid class 
					if (tbl_cell.childNodes.length > 0 && tbl_cell.className != scrabble.drag.forbid){
						// cell can contain many DIV elements
						for (var d=0; d<tbl_cell.childNodes.length; d++){
							// childNodes should be DIVs, not \n childs
							if (tbl_cell.childNodes[d].tagName == 'DIV'){ // and yes, it should be uppercase
								query += 'p[]=' + tbl_cell.childNodes[d].id + '_' + t + '_' + r + '_' + c + '&';
							}
						}
					}
				}
			}
		}
		// if tables are empty print nice message
		if (query == ''){
			message = 'Table is empty!';
		}
		// display query string
		else{
			// cut last '&'
			query = query.substring(0, query.length -1);
			// call multiple-parameters.php and show accepted parameters
			//popbox = window.open('/my/multiple-parameters.php?'+query,'Mypop','width=330,height=140,scrollbars=yes');
			popbox = window.open('multiple-parameters.php?'+query,'Mypop','width=330,height=140,scrollbars=yes');
		}*/
	};


	//
	// public methods and properties
	//

	return  {
        // public parameters
        hover_color   : '#E7AB83',	// hover color
        bound         : 25,			// bound width for autoscroll
        speed         : 20,			// scroll speed in milliseconds
        forbid        : 'forbid',	// cell class name where draggable element can not be dropped
        drop_option   : 'single',	// drop_option has three options: multiple, single and switch
        obj           : false,		// draggable object
		tripleWord	  : 'tripleWordCells', //tripleWordCells
		doubleWord	  : 'doubleWordCells',
		tripleLetter  : 'tripleLetterCells',
		doubleLetter  :	'doubleLetterCells',
		tripleWordText	  : 'TRIPLE WORD', //tripleWordCells
		doubleWordText	  : 'DOUBLE WORD',
		tripleLetterText  : 'TRIPLE LETTER',
		doubleLetterText  :	'DOUBLE LETTER',
		
		// assign public pointers
		init: init,
		enable_drag: enable_drag,
		// autoscroll should be public because of setTimeout recursive call in autoscroll
		autoscrollX: autoscrollX,
		autoscrollY: autoscrollY,
		currentTokens: currentTokens,
		triplewordTokens: triplewordTokens,
		doublewordTokens: doublewordTokens,
		doubleletterTokens: doubleletterTokens,
		tripleletterTokens: tripleletterTokens ,
			
		myhandler_clicked   : function(){},
		myhandler_moved     : function(){},
		myhandler_notmoved  : function(){},
		myhandler_dropped   : function(){},
		myhandler_switched  : function(){},
		myhandler_cloned    : function(){},
		myhandler_notcloned : function(){},
		myhandler_deleted   : function(){},
		myhandler_undeleted : function(){}
	}; // end of public (return statement)	
	
}());

 function oc(a)
{
  var o = {};
  for(var i=0;i<a.length;i++)
  {
    o[a[i]]='';
  }
  return o;
}

function makeTable()
{ 
	var row = new Array(); 
	var cell = new Array();

	var table_rows = 15; 
	var table_columns = 15; 

	var tab=document.createElement('table'); 
	//tab.setAttribute('id','mainTable');
	tab.setAttribute('border','1');
	//tab.setAttribute('width','100pt');
	//tab.setAttribute('height','100pt');
	tab.setAttribute('cellspacing','0');
	//tab.setAttribute('align','left');
	/*var col1 = document.createElement('tr');
	var row1 = document.createElement('td');
	row1.setAttribute('id', 'mainTable');
	var row2 = document.createElement('td');
	row2.setAttribute('id', 'scoreTable');
	var cell = document.createElement('td');
	var celltext=document.createTextNode("TRIPLE WORD")
	cell.appendChild(celltext);
	row2.appendChild(cell); */
	var count = 0;
	for(var i = 0; i < table_rows; i++)
	{
		row[i] = document.createElement('tr');
		for(var j = 0; j < table_columns; j++)
		{
			var value = (i*15)+j;
			cell[j] = document.createElement('td');
			cell[j].setAttribute('id', 'cell_' + value);
			cell[j].setAttribute('class', 'boardToken');
				
			if(value in oc(triplewordTokens))
			{
				cell[j].setAttribute('class', 'tripleWordCells');
				var celltext=document.createTextNode("TRIPLE WORD");
				cell[j].appendChild(celltext);
			}
			else if(value in oc(doublewordTokens))
			{
				cell[j].setAttribute('class', 'doubleWordCells');
				var celltext=document.createTextNode("DOUBLE WORD");
				cell[j].appendChild(celltext);
			}
			else if(value in oc(doubleletterTokens))
			{
				cell[j].setAttribute('class', 'doubleLetterCells');
				var celltext=document.createTextNode("DOUBLE LETTER");
				cell[j].appendChild(celltext);
			}	
			else if(value in oc(tripleletterTokens))
			{
				cell[j].setAttribute('class', 'tripleLetterCells');
				var celltext=document.createTextNode("TRIPLE LETTER");
				cell[j].appendChild(celltext);
			}	
			//cell[j].appendChild(divElement);
			row[i].appendChild(cell[j]); 
			count++;
		}
		tab.appendChild(row[i])
		
	}	
	
	//col1.appendChild(row1); 
	//col1.appendChild(row2); 
	//tab.appendChild(col1);
	//document.getElementById('drag_table').appendChild(tab);
	var scoreTable=document.createElement('table'); 
	scoreTable.setAttribute('border','1');
	//tab.setAttribute('width','100pt');
	//tab.setAttribute('height','100pt');
	scoreTable.setAttribute('align','right');
	scoreTable.setAttribute('cellspacing','0');
	
	var row = document.createElement('tr');
	var cell = document.createElement('td');
	var celltext=document.createTextNode("TRIPLE WORD")
	cell.appendChild(celltext);
	row.appendChild(cell); 
	scoreTable.appendChild(	row);
	//jQuery('#'+ cell_className.id).append(tab);
	document.getElementById('drag_table').appendChild(tab);
	var scoreDiv = document.createElement('div');
	scoreDiv.setAttribute('align','center');
	var scoreTable = document.createElement('table');
	//scoreTable.setAttribute('id','tokenTable');
	var scoreRow = document.createElement('tr');
	var scoreCells = new Array();
	for(var i = 0; i < 8; i ++)
	{
		scoreCells[i] = document.createElement('td');
		scoreCells[i].setAttribute('id','token'+ (i+1));
		scoreCells[i].setAttribute('class','tokens');
		scoreRow.appendChild(scoreCells[i]);
	}	
	scoreTable.appendChild(scoreRow);
	scoreDiv.appendChild(scoreTable);
	document.getElementById('tokens_table').appendChild(scoreDiv);
}	

// enables / disables dragging
function toggle_dragging(chk){
	scrabble.drag.enable_drag(chk.checked);
}


function getAllTokens()
{
	return ['A','A','A','A','A','A','A','A','A','B','B','C','C','D','D','D','D','E','E','E','E','E','E','E','E','E','E','E','E','F','F','G','G','G','H','H','I','I','I','I','I','I','I','I','I','J','K','L','L','L','L','M','M','N','N','N','N','N','N','O','O','O','O','O','O','O','O','P','P','Q','R','R','R','R','R','R','S','S','S','S','T','T','T','T','T','T','U','U','U','U','V','V','W','W','X','Y','Y','Z',' ',' '];

}

function setTokenValues()
{
	var str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ ";
	for(var i=0; i<str.length; i++)
	   {
	      var nextChar = str.charAt(i);
		  if(nextChar == "A" || nextChar == "E"  || nextChar == "I"  || nextChar == "L"  || nextChar == "N"  || nextChar == "O"  || nextChar == "R"  				|| nextChar == "S"  || nextChar == "T"  || nextChar == "U")
		     tokenValues[nextChar] = 1;
		 else if(nextChar == "D" || nextChar == "G" ) 
			  tokenValues[nextChar] = 2;
		 else if(nextChar == "B" || nextChar == "C" || nextChar == "M" || nextChar == "P" ) 
			  tokenValues[nextChar] = 3;
		 else if(nextChar == "F" || nextChar == "H" || nextChar == "V" || nextChar == "W" ||  nextChar == "Y"  ) 
			  tokenValues[nextChar] = 4;			  
		 else if(nextChar == "K"  ) 
			  tokenValues[nextChar] = 5; 
		  else if(nextChar == "J" || nextChar == "X" ) 
			  tokenValues[nextChar] = 8;
		  else if(nextChar == "Q" || nextChar == "Z" ) 
			  tokenValues[nextChar] = 10;
		  else tokenValues[nextChar] = '';
		  
	   }
}

function getTokenValue(a)
{
 return tokenValues[a];
}

function getNewTokens(value)
{
 var randomnumber;
 var tokens = [];
 var allTokens = getAllTokens();
 var usedTokens = JSON.parse(get('USEDTOKENS'));
 if(usedTokens != null)
 allTokens = allTokens.removeArray(usedTokens);
 for(var i = 0; i < value; i++) 
	 {
		leftTokensLength = allTokens.length;
        allTokens.shuffle(); 
		randomnumber=Math.floor(Math.random()*leftTokensLength);
		token = allTokens[randomnumber];
		tokens.push(token);
		allTokens.remove(token);
  	//leftTokens.splice(randomnumber,1);
	 }	
 return tokens;
 }	
 
 function fillTokens()
 {
	/*if(get('tokenFree') == "free")
	{
		set('tokenFree','inuse');
	}	
	else 
	{
		var statusMsg =  new gadgets.MiniMessage("message", document.getElementById("messagebox3"));
		statusMsg.createTimerMessage("Token container in use. Try again", 5);	
		return;
	}*/
	var usedTokens = JSON.parse(get('USEDTOKENS'));
	if(!usedTokens || usedTokens.length == 0)
		usedTokens = [];
	var tokens = jQuery(".tokens:not(:parent)");
	//var newTokens = getNewTokens(tokens.length - 1);
	var reqdTokens = tokens.length - 1;
	//if(reqdTokens == 7)
	//  return;	
	if(100 - usedTokens.length < reqdTokens)
		reqdTokens = 100 - usedTokens.length;
	var newTokens = getNewTokens(reqdTokens);
	//var newTokens =[];
		
	for(var j = 0; j < newTokens.length;j++)
	{
		jQuery('#'+ tokens[j].id).html('<div class="drag token">' + newTokens[j] +'<sub class="subscripts">'+ getTokenValue(newTokens[j])+'</sub></div>');
	}
	var userId = wave.getViewer().getId() + 'currentCells';
	var userTokens = jQuery(".tokens:parent");
	var plateTokens = new Array();
	for(var j = 0; j < userTokens.length;j++)
	{
		plateTokens[j] = jQuery('#'+ userTokens[j].id).text().charAt(0);
	}
	
	set(userId, JSON.stringify(plateTokens));
	set('USEDTOKENS', JSON.stringify(usedTokens.addArray(newTokens)));
	scrabble.drag.init();
	jQuery('#pick').attr('disabled', 'disabled');
	set('pickTurn',getNextUser(get('pickTurn')));
	//set('tokenFree','free');
 }
 
 
 function checkInitialLegal()
 {
	if(!jQuery("#cell_112 > div").length > 0)
		    return false;
	else 
	{
	var cellNums = [];
	for(var i = 0; i <scrabble.drag.currentTokens.length; i++)
	{
		var cellId = scrabble.drag.currentTokens[i].id;
		cellNums.push(cellId.substring(5));
	}	
	if(cellNums.length == 1)
	{
		set(wave.getViewer().getId(),(2*getValue(112)));
		return true;
	}	
	cellNums.sort(function(a,b){return a - b});	
	var cellStart = parseInt(cellNums[0]);
	var cellEnd = parseInt(cellNums[cellNums.length - 1]);
	var cellRow = Math.floor(cellStart/15);
	var cellCol = Math.floor(cellStart%15);
	var isLegal = true;
	var score = 0;
	var triplewordCount = 0;
	var doublewordCount = 0;
	if( Math.floor(cellEnd/15) == cellRow)
	{
		for(var i = cellStart; i < cellEnd + 1; i++)
		{
			if(!jQuery('#cell_' + i +' > div').length > 0)
				return false;
			
			if(i in oc(scrabble.drag.triplewordTokens))
				triplewordCount++;
			else if(i in oc(scrabble.drag.doublewordTokens))
				doublewordCount++;
			
			score = score + getValue(i);
		}		
	}
	else if(( Math.floor(cellEnd%15) == cellCol))
	{
		for(var j = 0; j < cellNums.length ; j ++)
		{
		 if( (cellNums[j] % 15) != cellCol)
			return false;
		}
		for(var i = cellStart; i < cellEnd + 1; i=i+15)
		{
			if(!jQuery('#cell_' + i +' > div').length > 0)
				return false;	
					
			if(i in oc(scrabble.drag.triplewordTokens))
				triplewordCount++;
			else if(i in oc(scrabble.drag.doublewordTokens))
				doublewordCount++;
			
			score = score + getValue(i);	
		}	
	}	
	else
		isLegal = false;
	if(isLegal)
	{
		for(var i = 0; i < doublewordCount; i++)
			score *=2;
		for(var j = 0; j < triplewordCount; j++)
			score *=3;
		var	participantId = wave.getViewer().getId();
		set(participantId,score);
	}		
	return isLegal;
	}	
 }
 
 function disableBtns()
 {
	jQuery('#done').attr('disabled', 'disabled');
	jQuery('#skip').attr('disabled', 'disabled');
	jQuery('#shuffle').attr('disabled', 'disabled');
	jQuery('#challenge').removeAttr('disabled');
 }
 
 function enableBtns()
 {
	jQuery('#done').removeAttr('disabled');
	jQuery('#skip').removeAttr('disabled');
	jQuery('#shuffle').removeAttr('disabled');
	jQuery('#challenge').attr('disabled', 'disabled');
 }
 
 function clearTokens()
 {
	var tokens = jQuery(".tokens");
	for(var j = 0; j < 8;j++)
	{
		jQuery('#'+ tokens[j].id).html('');
	}
 }
 
 function openShuffleTurnDialog()
 {
	var $shuffledialog = jQuery('<div></div>')
		.html('Are you sure you want to shuffle your letters? You will miss your chance to play this turn')
		.dialog({
			autoOpen: false,
			title: 'Shuffle Letters',
			resizable: false,
			height:100,
			width: 400,
			modal: true,
			buttons: {
				'No': function() {
				jQuery(this).dialog('close');	
				},
				'Yes': function() {
				shuffleTurn(this);
				}				
			}
		});
		$shuffledialog.dialog('open');
 }
 
 function openPlayTurnDialog()
 {
	var $openPlayTurndialog = jQuery('<div></div>')
		.html('Are you sure you want to play this word?')
		.dialog({
			autoOpen: false,
			title: 'Play Word',
			resizable: false,
			height:100,
			width: 400,
			modal: true,
			buttons: {
				'No': function() {
				jQuery(this).dialog('close');	
				},
				'Yes': function() {
				playTurn(this);
				}				
			}
		});
		$openPlayTurndialog.dialog('open');
 }
 
 
 function shuffleTurn(dialog)
 {
		returnCells();
		var userId = wave.getViewer().getId() + 'currentCells';
		var userTokens = JSON.parse(get(userId));
		alert(userTokens.length);
		if(userTokens)
		{
			alert(userTokens.length);
			var usedTokens = JSON.parse(get('USEDTOKENS'));
			alert(usedTokens.length);
			if(usedTokens && usedTokens.length > 0)
			{
				alert(usedTokens.length);
				clearTokens();
				set('USEDTOKENS', JSON.stringify(usedTokens.addArray(userTokens)));
				fillTokens();
				skipTurn();
			}
		
		}
		jQuery(dialog).dialog('close');
 }
 
 function skipTurn(dialog)
 {
		returnCells();
		set('currentUser',getNextUser(get('currentUser')));
		disableBtns();
		jQuery(dialog).dialog('close');
 }
 
 function openSkipTurnDialog()
 {
	var $skipdialog = jQuery('<div></div>')
		.html('Are you sure you want to skip your turn?')
		.dialog({
			autoOpen: false,
			title: 'Skip Turn',
			resizable: false,
			height:100,
			width: 400,
			modal: true,
			buttons: {
				'No': function() {
				jQuery(this).dialog('close');	
				},
				'Yes': function() {
				skipTurn(this);
				}				
			}
		});
	$skipdialog.dialog('open');
 }
 
 function confirmAction(text)
 {
	return confirm(text);
 }
 
 function playTurn(dialog)
 {
	jQuery(dialog).dialog('close');
	scrabble.drag.currentTokens = jQuery(".container1 td:has(div)").filter(":not(.forbid)");
	if(scrabble.drag.currentTokens.length == 0)
		return;
	var usedTokens = JSON.parse(get('USEDTOKENS'));
	var legal = false;
	var i = 0;
	if(!get('board'))
	{
		legal = checkInitialLegal();
		usedTokens = [];
	}	 
	else legal = checkIfLegal();
	if(legal)
	{
		if(!get('board'))
		  set('board','notempty');
		var userId = wave.getViewer().getId() + 'currentCells';
		var userTokens = JSON.parse(get(userId));
		//calculateScores();
		for(var j = 0; j < scrabble.drag.currentTokens.length;j++)
		{
			var cellId = scrabble.drag.currentTokens[j].id;
			if(cellId.match(window.CELL_STATE))
			{
					jQuery('#' + cellId).addClass('forbid');
					var cellObject = {};
					cellObject[cellId] = ''+ jQuery('#'+ cellId).html();
					var text = jQuery('#'+ cellId).text();
					wave.getState().submitDelta(cellObject);
					userTokens.remove(text.charAt(0));
			}	
		}
		scrabble.drag.currentTokens = [];
	/*	while(scrabble.drag.currentTokens.length > 0)
		{
			var cellId = scrabble.drag.currentTokens[i].id;
			if(cellId.match(window.CELL_STATE))
				{
					jQuery('#' + cellId).addClass('forbid');
					var cellObject = {};
					cellObject[cellId] = ''+ jQuery('#'+ cellId).html();
					var text = jQuery('#'+ cellId).text();
					wave.getState().submitDelta(cellObject);
					userTokens.remove(text.charAt(0));
					scrabble.drag.currentTokens.remove(scrabble.drag.currentTokens[i]);
				}	
		}*/
		set('currentUser',getNextUser(get('currentUser')));
		set(userId, JSON.stringify(userTokens));
		jQuery('#done').attr('disabled', 'disabled');
		jQuery('#pick').removeAttr('disabled');
		fillTokens();
	}
	else
	{
		returnCells();
	}
}
 
 
 function getNextUser(user)
 {
	var participants = wave.getParticipants();
	var numPeople = participants.length;
     if (numPeople > 0) {
		 var currentUser = user;
	    for (var i = 0; i < numPeople; ++i) {
		 var participant = participants[i];
		 participantId = participant.getId();
		 if(currentUser == participantId)
		 {
			if(i == numPeople - 1)
				return participants[0].getId();
			else return participants[i+1].getId();	
		 }	
		}
	}	
 }
 
 
 function iscellFilled(cellId)
 {
	if(jQuery('#' + cellId).hasClass("forbid"))
			return true;
	else return false; 
 }
 
 function iscellOccupied(cellId)
 {
	if(jQuery('#cell_' + cellId +' > div').length > 0)
			return true;
	else return false; 
 }
 
 function returnCells()
 {
	var tokens = jQuery(".tokens:not(:parent)");
	var newTokens = scrabble.drag.currentTokens;
	var count = 0;
	for(var j = 0; j < newTokens.length;j++)
	{
		query = jQuery('#'+ newTokens[j].id);
		jQuery('#'+ tokens[j].id).html(query.html());
		
		if(query.hasClass(scrabble.drag.tripleWord))
			query.html(scrabble.drag.tripleWordText);
		else if(query.hasClass(scrabble.drag.doubleWord))
			query.html(scrabble.drag.doubleWordText);
		else if(query.hasClass(scrabble.drag.tripleLetter))
			query.html(scrabble.drag.tripleLetterText);
		else if(query.hasClass(scrabble.drag.doubleLetter))
			query.html(scrabble.drag.doubleLetterText);
		else query.html("");	
	}	
	scrabble.drag.currentTokens = [];
	scrabble.drag.init();
  }
 
 function checkIfLegal()
 {
	var cellNums = [];
	for(var i = 0; i <scrabble.drag.currentTokens.length; i++)
	{
		var cellId = scrabble.drag.currentTokens[i].id;
		cellNums.push(cellId.substring(5));
	}	
/*	if(cellNums.length == 1)
		return iscellMoveLegal("cell_" + cellNums[0]);*/
	cellNums.sort(function(a,b){return a - b});	
	var cellStart = parseInt(cellNums[0]);
	var cellEnd = parseInt(cellNums[cellNums.length - 1]);
	var cellRow = Math.floor(cellStart/15);
	var cellCol = Math.floor(cellStart%15);
	var isLegal = false;
	var score = 0;
	var tempScore = 0;
	var triplewordCount = 0;
	var doublewordCount = 0;
	if( Math.floor(cellEnd/15) == cellRow)
	{
		for(var i = cellStart; i < cellEnd + 1; i++)
		{
			if(!jQuery('#cell_' + i +' > div').length > 0)
				return false;
			
			if(!isLegal)
			  if(!jQuery('#cell_' + i).hasClass("forbid"))
			    isLegal = iscellMoveLegal("cell_" + i);
				
			if(!jQuery('#cell_' + i).hasClass("forbid"))	
			{
				if(i in oc(scrabble.drag.triplewordTokens))
					triplewordCount++;
				else if(i in oc(scrabble.drag.doublewordTokens))
					doublewordCount++;
				score = score + getVerticalWordValue(i);
			}
		}
		if(isLegal)
		{
			tempScore = tempScore + getValue(cellStart);
			var tokenPos = cellStart;
			if(cellCol > 0)
			{
			  tokenPos--;
			  while(tokenPos > -1 && (Math.floor(tokenPos/15) == cellRow) && iscellOccupied(tokenPos))
			  {
				tempScore += getValue(tokenPos);
     			 tokenPos--;
			  }	 
			}	
			tokenPos = cellStart;	
			if(cellCol < 14) 
			{
			  tokenPos++;	
			  while(tokenPos < 225 && (Math.floor(tokenPos/15) == cellRow) && iscellOccupied(tokenPos))
			  {
				tempScore += getValue(tokenPos);
				tokenPos++;	
			  }	
			}
			for(var i = 0; i < doublewordCount; i++)
				tempScore *=2;
			for(var j = 0; j < triplewordCount; j++)
				tempScore *=3;	
			var participantId = wave.getViewer().getId();
			score = score + tempScore + parseInt(get(participantId));	
			set(participantId,score);
		}		
	}
	else if(( Math.floor(cellEnd%15) == cellCol))
	{
		for(var j = 0; j < cellNums.length ; j ++)
		{
		 if( (cellNums[j] % 15) != cellCol)
			return false;
		}
		for(var i = cellStart; i < cellEnd + 1; i=i+15)
		{
			if(!jQuery('#cell_' + i +' > div').length > 0)
				return false;	
			if(!isLegal)
			  if(!(jQuery('#cell_' + i).hasClass("forbid")))
			    isLegal = iscellMoveLegal("cell_" + i);
			
			if(!(jQuery('#cell_' + i).hasClass("forbid")))
			{			  
				if(i in oc(scrabble.drag.triplewordTokens))
					triplewordCount++;
				else if(i in oc(scrabble.drag.doublewordTokens))
					doublewordCount++;
				score = score + getHorizontalWordValue(i);	
			}	
		}
		if(isLegal)
		{
			tempScore = tempScore + getValue(cellStart);
			var tokenPos = cellStart;
			if(cellRow > 0)
			{
			  tokenPos = tokenPos - 15;
			  while(tokenPos > -1 && iscellOccupied(tokenPos))
			  {
				tempScore = tempScore + getValue(tokenPos);
				tokenPos = tokenPos - 15;
			  }
			}	
			tokenPos = cellStart;	
			if(cellRow < 14) 
			{
			   tokenPos = tokenPos + 15;
			  while(tokenPos < 225 && iscellOccupied(tokenPos))
			  {
				tempScore = tempScore + getValue(tokenPos);
				tokenPos = tokenPos + 15;
			  } 	
			}
			for(var i = 0; i < doublewordCount; i++)
				tempScore *=2;
			for(var j = 0; j < triplewordCount; j++)
				tempScore *=3;	
			var participantId = wave.getViewer().getId();
			score = score + tempScore + parseInt(get(participantId));	
			set(participantId,score);
		}		
	}	
	else
		isLegal = false;
	return isLegal;
 }
 
 
 function getVerticalWordValue(value)
 {
	var score = getValue(value);
	var tokenPos = value;
	var hasVerticalWord = false;
	if(value > 14)
	{
	  tokenPos+= -15;
	  while(tokenPos > -1 && iscellFilled("cell_" + tokenPos))
	  {
		score+= getValue(tokenPos);
		tokenPos+= -15;
		if(!hasVerticalWord)
		 hasVerticalWord = true;	
	  }
	}	
	tokenPos = value;	
	if(value < 210) 
	{
	  tokenPos+= 15;
	  while(tokenPos < 225 && iscellFilled("cell_" + tokenPos))
	  {
		score += getValue(tokenPos);
		tokenPos+= 15;
		if(!hasVerticalWord)
		 hasVerticalWord = true;	
	  } 	
	}	
	if(!hasVerticalWord)
		 return 0;	
	if(value in oc(scrabble.drag.triplewordTokens))
		return score * 3;
	else if(value in oc(scrabble.drag.doublewordTokens))
		return score * 2;
    else return score;	
 }
 
 function getHorizontalWordValue(value)
 {
	var score = getValue(value);
	var tokenPos = value;
	var hasHorzWord = false;
	var cellRow = Math.floor(value/15);
	if(value%15 > 0)
	{
	  tokenPos--;
	  while(tokenPos > -1 && (Math.floor(tokenPos/15) == cellRow) && iscellFilled("cell_" + tokenPos))
	  {
	   	score += getValue(tokenPos);
		tokenPos--;
		if(!hasHorzWord)
		 hasHorzWord = true;	
	  }	 
	}	
	tokenPos = value;	
	if(value%15 < 14) 
	{
	  tokenPos++;	
	  while(tokenPos < 225 && (Math.floor(tokenPos/15) == cellRow) && iscellFilled("cell_" + tokenPos))
	  {
		score += getValue(tokenPos);
		tokenPos++;	
		if(!hasHorzWord)
		 hasHorzWord = true;	
	  }	
	}
	if(!hasHorzWord)
		return 0;		
	if(value in oc(scrabble.drag.triplewordTokens))
		return score * 3;
	else if(value in oc(scrabble.drag.doublewordTokens))
		return score * 2;
    else return score;	
 }
 
 function getValue(value)
 {
	var text = jQuery('#cell_' + value).text();
	if(text.charAt(0) == ' ')
		return 0;
	var score = parseInt(text.charAt(1));
	if(!jQuery('#cell_' + value).hasClass("forbid"))
	{
		if(value in oc(scrabble.drag.tripleletterTokens))
			return score * 3;
		else if(value in oc(scrabble.drag.doubleletterTokens))
			return score * 2;
	}
	return score;
 }	
 
 function iscellMoveLegal(cellId)
 {
	var cellNum = parseInt(cellId.substring(5));
	var legal = false;
	if(cellNum > 14 && iscellFilled("cell_" + (cellNum - 15)))
		 return true;
	else if(cellNum%15 > 0 && iscellFilled("cell_" + (cellNum - 1)))
		return true;
	else if(cellNum%15 < 14 && iscellFilled("cell_" + (cellNum + 1)))
		return true;
    else if(cellNum < 210 && iscellFilled("cell_" + (cellNum + 15)))
		return true;	
	else return false; 
}		
		
function containsCell(sourceArray, element)
 {
	 var ret = false;
	 for (var i = 0; i < sourceArray.length; i++) {
     if (sourceArray[i].id == element.id) {
      ret = true;
      break;
    }
  }  
  return ret;
 } 
 
function removeCell(sourceArray, element)
{
 for (var i = 0; i < sourceArray.length; i++) {
    if (sourceArray[i].id == element.id) {
	    sourceArray.splice(i, 1);
      break;
    }
  }
}

//checks the document and waits until it's ready to be manipulated, known as the ready event
jQuery(document).ready(function(){
   scrabble.drag.init();
   
 });
 
//window.onload = function(){scrabble.drag.init()};

 
